home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / Colin’s ABC’s / Prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  3.7 KB  |  179 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Prefs.c - Handle preferences file
  3.  */
  4.  
  5. # include    <GestaltEqu.h>
  6. # include    <Folders.h>
  7. # include    <Script.h>
  8.  
  9. # include    "TransSkel.h"
  10.  
  11. # include    "C-ABC.h"
  12. # if ENABLE_DEBUG
  13. # include    "Debug.h"
  14. # endif
  15.  
  16.  
  17. static OSType
  18. MakePrefsFileFSS (FSSpec *fss)
  19. {
  20. long    result;
  21. short    vRefNum;
  22. long    dirID;
  23. OSErr    err;
  24.  
  25.     if (!SkelQuery (skelQHasGestalt)
  26.         || Gestalt (gestaltFindFolderAttr, &result) != noErr
  27.         || ((1 << gestaltFindFolderPresent) & result) == 0)
  28.         return (gestaltUnknownErr);
  29.     err = FindFolder (kOnSystemDisk, kPreferencesFolderType,
  30.                         kDontCreateFolder, &vRefNum, &dirID);
  31.     if (err == noErr)
  32.         err = FSMakeFSSpec (vRefNum, dirID, prefsFileName, fss);
  33.     return (err);
  34. }
  35.  
  36.  
  37. static void
  38. InterpPreferences (Handle h, long size, Prefs *prefs)
  39. {
  40. Boolean    result = false;            /* assume the worst */
  41.  
  42.     switch (* (short *) *h)        /* switch on version number */
  43.     {
  44.     case 2:                        /* only version 2 is used currently */
  45.         if (size == sizeof (Prefs))
  46.         {
  47.             *prefs = * (Prefs *) *h;
  48.             result = true;
  49.         }
  50.         break;
  51.     }
  52.     if (!result)    /* data malformed or unknown version */
  53.     {
  54. # if ENABLE_DEBUG
  55.         DisplayCString ("prefs file contents are malformed.\r");
  56. # endif
  57.     }
  58. }
  59.  
  60.  
  61. /*
  62.  * Read preferences file to get preferences values.
  63.  * The preferences structure should be initialized by the caller.
  64.  * If the preferences file can't be read or is malformed, the structure
  65.  * will be undisturbed; otherwise the values in the file override the
  66.  * defaults.
  67.  */
  68.  
  69. void
  70. ReadPreferences (Prefs *prefs)
  71. {
  72. FSSpec    fss;
  73. short    vRefNum;
  74. long    size, count;
  75. Handle    h;
  76. OSErr    err;
  77.  
  78.     if ((err = MakePrefsFileFSS (&fss)) != noErr)
  79.     {
  80. # if ENABLE_DEBUG
  81.         DisplayCString ("No Preferences file, err = ");
  82.         DisplayLong (err);
  83.         DisplayLn ();
  84. # endif
  85.         return;
  86.     }
  87.     if (FSpOpenDF (&fss, fsRdPerm, &vRefNum) != noErr)
  88.     {
  89. # if ENABLE_DEBUG
  90.         DisplayCString ("Cannot open prefs file.\r");
  91. # endif
  92.         return;
  93.     }
  94.     if (GetEOF (vRefNum, &size) == noErr)
  95.     {
  96. # if ENABLE_DEBUG
  97.         DisplayCString ("size of prefs file: ");
  98.         DisplayLong (size);
  99.         DisplayLn ();
  100. # endif
  101.         /* size must be at least enough for the version number at the front */
  102.         if (size >= sizeof (short))
  103.         {
  104.             /*
  105.              * Read the file into a generic block of memory.  This strategy
  106.              * is used in case the Prefs structure undergoes modification in
  107.              * the future.  By reading it into a generic block and examining
  108.              * the version number, the block can be interpreted appropriately.
  109.              */
  110.  
  111.             if ((h = NewHandle (size)) != (Handle) nil)
  112.             {
  113.                 HLock (h);
  114.                 count = size;
  115.                 if (FSRead (vRefNum, &count, *h) == noErr)
  116.                 {
  117.                     if (count == size)
  118.                         InterpPreferences (h, size, prefs);
  119.                 }
  120.                 HUnlock (h);
  121.                 DisposeHandle (h);
  122.             }
  123.         }
  124.     }
  125.     (void) FSClose (vRefNum);
  126. }
  127.  
  128.  
  129. void
  130. WritePreferences (Prefs *prefs)
  131. {
  132. FSSpec    fss;
  133. short    vRefNum;
  134. long    size;
  135. Handle    h;
  136. OSErr    err;
  137.  
  138.     if ((err = MakePrefsFileFSS (&fss)) != noErr)
  139.     {
  140. # if ENABLE_DEBUG
  141.         DisplayCString ("No Preferences file, err = ");
  142.         DisplayLong (err);
  143.         DisplayLn ();
  144. # endif
  145.         if (err != fnfErr)
  146.             return;
  147. # if ENABLE_DEBUG
  148.         DisplayCString ("Creating prefs file.\r");
  149. # endif
  150.         err = FSpCreate (&fss, creatorType, prefsFileType, smSystemScript);
  151.         if (err != noErr)
  152.         {
  153. # if ENABLE_DEBUG
  154.             DisplayCString ("prefs file creation error: ");
  155.             DisplayLong (err);
  156.             DisplayLn ();
  157. # endif
  158.             return;
  159.         }
  160.     }
  161.     if (FSpOpenDF (&fss, fsWrPerm, &vRefNum) != noErr)
  162.     {
  163. # if ENABLE_DEBUG
  164.         DisplayCString ("Cannot open prefs file for writing.\r");
  165. # endif
  166.         return;
  167.     }
  168.     size = sizeof (Prefs);
  169.     FSWrite (vRefNum, &size, (Ptr) prefs);
  170.     if (size != sizeof (Prefs))
  171.     {
  172. # if ENABLE_DEBUG
  173.         DisplayCString ("error writing prefs file.\r");
  174. # endif
  175.         size = 0;    /* clobber contents to prevent misinterpretation on next read */
  176.     }
  177.     (void) SetEOF (vRefNum, sizeof (Prefs));
  178.     (void) FSClose (vRefNum);
  179. }